#include "Method.h"
#include "MethodDEClassical.h"

Method * Method::createMethod(Method::SubType subType, Problem * problem, unsigned int popSize, unsigned int iterations) {
    Method * pMethod = NULL;
    switch (subType) {

    case DEClassical:
        pMethod = new MethodDEClassical(subType, problem, popSize, iterations);
        break;
    default:
        pMethod = new MethodDEClassical(subType, problem, popSize, iterations);
    }
    return pMethod;
}

Method::Method(const SubType & subType, Problem * problem, unsigned int popSize, unsigned int iterations):
    mSubType(subType),
    problem(problem),


    populationSize(popSize),
    iterations(iterations) {
    switch (subType) {
    case DEClassical:
        name="DEClassical";
        break;
    default:
        name="DEClassical";
    }
}

Method::~Method() {}

std::vector<double> & Method::initializeCost(matrix & population, std::vector<double> & cost)
{
     unsigned int i;
     for (i=0; i<getPopulationSize(); i++) {
          cost[i]=getProblem()->computeValue(population[i]);
     }
     return cost;
}

matrix & Method::initialize(matrix & population)
{
     unsigned int dim=getProblem()->getDimention();
     unsigned int i, j;
     double lower, upper, random;
     RandomLib::Random r;          // Create r
     r.Reseed();
     //MATRIX : population size * dimention of object function
     for(j=0; j<getProblem()->getDimention(); j++) {
          lower=getProblem()->getCoordinates()[j].getLowerBound();
          upper=getProblem()->getCoordinates()[j].getUpperBound();
          for (i=0; i<getPopulationSize() ; i++ ) {
               //generate random number from lower bound to upper
               random=r.Fixed()*(upper-lower)+lower;
               population[i][j]=random;
          }
     }
     return population;
}
void Method::printMethod() {
    std::cout<<getName()<<"  population size: "<<getPopulationSize()<<std::endl;
    getProblem()->printProblem();
}

void Method::printPopulation(matrix & population) {
    unsigned int i,j;
    for(i=0; i<populationSize; i++)
    {
        for(j=0; j<problem->getDimention(); j++)
            std::cout<<population[i][j]<<" ";
            std::cout<<std::endl;
    }
}
